home *** CD-ROM | disk | FTP | other *** search
/ AMIGA-CD 2 / Amiga-CD - Volume 2.iso / gepackte_disketten / 1994 / 08_94_5.dms / 08_94_5.adf / term-4.0-Source.lha / termClip.c < prev    next >
C/C++ Source or Header  |  1994-06-16  |  10KB  |  566 lines

  1. /*
  2. **    termClip.c
  3. **
  4. **    Clipboard support routines
  5. **
  6. **    Copyright © 1990-1994 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12. STATIC struct IFFHandle    *ClipHandle;
  13. STATIC STRPTR         ClipBuffer,
  14.              ClipIndex;
  15. STATIC LONG         ClipSize,
  16.              ClipLength;
  17.  
  18.     /* CloseClip():
  19.      *
  20.      *    Close clipboard handle, stop reading.
  21.      */
  22.  
  23. VOID
  24. CloseClip()
  25. {
  26.     if(ClipHandle)
  27.     {
  28.         CloseIFF(ClipHandle);
  29.  
  30.         if(ClipHandle -> iff_Stream)
  31.             CloseClipboard((struct ClipboardHandle *)ClipHandle -> iff_Stream);
  32.  
  33.         FreeIFF(ClipHandle);
  34.  
  35.         ClipHandle = NULL;
  36.     }
  37.  
  38.     if(ClipBuffer)
  39.     {
  40.         FreeVecPooled(ClipBuffer);
  41.  
  42.         ClipBuffer = NULL;
  43.     }
  44. }
  45.  
  46.     /* GetClip(STRPTR Buffer,WORD Len,BYTE Filter):
  47.      *
  48.      *    Read text data from clipboard and put it into the supplied buffer.
  49.      */
  50.  
  51. WORD __regargs
  52. GetClip(STRPTR Buffer,WORD Len,BYTE Filter)
  53. {
  54.     WORD BytesPut = 0;
  55.  
  56.         /* Is the read buffer already exhausted? */
  57.  
  58.     if(!ClipLength)
  59.     {
  60.             /* Is there still any data to read? */
  61.  
  62.         if(ClipSize)
  63.         {
  64.             WORD Size = MIN(ClipSize,1024);
  65.  
  66.                 /* Try to read the data and return failure if necessary. */
  67.  
  68.             if(ReadChunkBytes(ClipHandle,ClipBuffer,Size) != Size)
  69.                 return(-1);
  70.             else
  71.             {
  72.                 ClipSize    -= Size;
  73.                 ClipLength     = Size;
  74.                 ClipIndex     = ClipBuffer;
  75.             }
  76.         }
  77.         else
  78.         {
  79.                 /* We just parsed a single chunk, now go on and
  80.                  * look for another one.
  81.                  */
  82.  
  83.             if(!ParseIFF(ClipHandle,IFFPARSE_SCAN))
  84.             {
  85.                 struct ContextNode *ContextNode = CurrentChunk(ClipHandle);
  86.  
  87.                 if(ContextNode -> cn_Type == ID_FTXT)
  88.                 {
  89.                     WORD Size;
  90.  
  91.                     ClipSize    = ContextNode -> cn_Size;
  92.                     Size        = MIN(ClipSize,1024);
  93.  
  94.                     if(ReadChunkBytes(ClipHandle,ClipBuffer,Size) != Size)
  95.                         return(-1);
  96.                     else
  97.                     {
  98.                         ClipSize    -= Size;
  99.                         ClipLength     = Size;
  100.                         ClipIndex     = ClipBuffer;
  101.                     }
  102.                 }
  103.                 else
  104.                     return(-1);
  105.             }
  106.             else
  107.                 return(-1);
  108.         }
  109.     }
  110.  
  111.         /* The following loop processes the contents of
  112.          * the clipboard buffer read. Special characters
  113.          * such as LF and CR will be converted according
  114.          * to the current settings if enabled. No bytes
  115.          * will be lost, though.
  116.          */
  117.  
  118.     while(ClipLength && BytesPut < Len)
  119.     {
  120.         if(*ClipIndex == '\n')
  121.         {
  122.             if(Filter)
  123.             {
  124.                 *Buffer++ = *ClipIndex++;
  125.  
  126.                 BytesPut++;
  127.  
  128.                 ClipLength--;
  129.             }
  130.             else
  131.             {
  132.                 switch(Config -> TerminalConfig -> SendLF)
  133.                 {
  134.                     case LF_IGNORE:
  135.  
  136.                         ClipIndex++;
  137.                         ClipLength--;
  138.  
  139.                         break;
  140.  
  141.                     case LF_ASLFCR:
  142.  
  143.                         if(BytesPut + 2 <= Len)
  144.                         {
  145.                             *Buffer++ = '\n';
  146.                             *Buffer++ = '\r';
  147.  
  148.                             BytesPut += 2;
  149.  
  150.                             ClipLength--;
  151.                             ClipIndex++;
  152.                         }
  153.                         else
  154.                             return(BytesPut);
  155.  
  156.                         break;
  157.  
  158.                     case LF_ASLF:
  159.  
  160.                         *Buffer++ = *ClipIndex++;
  161.  
  162.                         BytesPut++;
  163.  
  164.                         ClipLength--;
  165.  
  166.                         break;
  167.                 }
  168.             }
  169.         }
  170.         else
  171.         {
  172.             if(*ClipIndex == '\r')
  173.             {
  174.                 if(Filter)
  175.                 {
  176.                     ClipIndex++;
  177.                     ClipLength--;
  178.                 }
  179.                 else
  180.                 {
  181.                     switch(Config -> TerminalConfig -> SendCR)
  182.                     {
  183.                         case CR_IGNORE:
  184.  
  185.                             ClipIndex++;
  186.                             ClipLength--;
  187.  
  188.                             break;
  189.  
  190.                         case CR_ASCRLF:
  191.  
  192.                             if(BytesPut + 2 <= Len)
  193.                             {
  194.                                 *Buffer++ = '\r';
  195.                                 *Buffer++ = '\n';
  196.  
  197.                                 BytesPut += 2;
  198.  
  199.                                 ClipLength--;
  200.                                 ClipIndex++;
  201.                             }
  202.                             else
  203.                                 return(BytesPut);
  204.  
  205.                             break;
  206.  
  207.                         case CR_ASCR:
  208.  
  209.                             *Buffer++ = *ClipIndex++;
  210.  
  211.                             BytesPut++;
  212.  
  213.                             ClipLength--;
  214.  
  215.                             break;
  216.                     }
  217.                 }
  218.             }
  219.             else
  220.             {
  221.                 register UBYTE c = *ClipIndex++;
  222.  
  223.                 ClipLength--;
  224.  
  225.                 if(!Filter || IsPrintable[c])
  226.                 {
  227.                     *Buffer++ = c;
  228.  
  229.                     BytesPut++;
  230.                 }
  231.             }
  232.         }
  233.     }
  234.  
  235.     return(BytesPut);
  236. }
  237.  
  238.     /* OpenClip():
  239.      *
  240.      *    Open the clipboard for sequential reading.
  241.      */
  242.  
  243. BYTE __regargs
  244. OpenClip(LONG Unit)
  245. {
  246.     BYTE Error;
  247.  
  248.     CloseClip();
  249.  
  250.     if(ClipBuffer = (STRPTR)AllocVecPooled(1024,MEMF_ANY))
  251.     {
  252.         if(ClipHandle = AllocIFF())
  253.         {
  254.             if(ClipHandle -> iff_Stream = (ULONG)OpenClipboard(Unit))
  255.             {
  256.                 InitIFFasClip(ClipHandle);
  257.  
  258.                 if(!OpenIFF(ClipHandle,IFFF_READ))
  259.                 {
  260.                     if(!StopChunk(ClipHandle,ID_FTXT,ID_CHRS))
  261.                     {
  262.                         if(!ParseIFF(ClipHandle,IFFPARSE_SCAN))
  263.                         {
  264.                             struct ContextNode *ContextNode = CurrentChunk(ClipHandle);
  265.  
  266.                             if(ContextNode -> cn_Type == ID_FTXT)
  267.                             {
  268.                                 ClipSize    = ContextNode -> cn_Size;
  269.                                 ClipLength    = 0;
  270.  
  271.                                 return(CLIPERR_NONE);
  272.                             }
  273.                             else
  274.                                 Error = CLIPERR_NOTEXT;
  275.                         }
  276.                         else
  277.                             Error = CLIPERR_NOTEXT;
  278.                     }
  279.                     else
  280.                         Error = CLIPERR_IFF;
  281.                 }
  282.                 else
  283.                     Error = CLIPERR_OPEN;
  284.             }
  285.             else
  286.                 Error = CLIPERR_OPEN;
  287.         }
  288.         else
  289.             Error = CLIPERR_MEM;
  290.     }
  291.     else
  292.         Error = CLIPERR_MEM;
  293.  
  294.     CloseClip();
  295.  
  296.     return(Error);
  297. }
  298.  
  299.     /* GetClipContents(LONG Unit,APTR *Buffer,LONG *Size):
  300.      *
  301.      *    Merge text contents of the clipboard into a single string.
  302.      */
  303.  
  304. BYTE __regargs
  305. GetClipContents(LONG Unit,APTR *Buffer,LONG *Size)
  306. {
  307.     struct IFFHandle    *Handle;
  308.     LONG             Bytes = 0;
  309.     APTR             Store = NULL;
  310.  
  311.     if(Handle = AllocIFF())
  312.     {
  313.         if(Handle -> iff_Stream = (ULONG)OpenClipboard(Unit))
  314.         {
  315.             InitIFFasClip(Handle);
  316.  
  317.             if(!OpenIFF(Handle,IFFF_READ))
  318.             {
  319.                 if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  320.                 {
  321.                     struct ContextNode *Node;
  322.  
  323.                     while(!ParseIFF(Handle,IFFPARSE_SCAN))
  324.                     {
  325.                         Node = CurrentChunk(Handle);
  326.  
  327.                         if(Node -> cn_Type == ID_FTXT)
  328.                             Bytes += Node -> cn_Size;
  329.                     }
  330.                 }
  331.  
  332.                 CloseIFF(Handle);
  333.             }
  334.  
  335.             if(Bytes)
  336.             {
  337.                 if(!OpenIFF(Handle,IFFF_READ))
  338.                 {
  339.                     if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  340.                     {
  341.                         if(Store = AllocVecPooled(Bytes,MEMF_ANY))
  342.                         {
  343.                             STRPTR             Index        = Store;
  344.                             LONG             BytesRead    = 0;
  345.                             struct ContextNode    *Node;
  346.  
  347.                             while(!ParseIFF(Handle,IFFPARSE_SCAN) && BytesRead < Bytes)
  348.                             {
  349.                                 Node = CurrentChunk(Handle);
  350.  
  351.                                 if(Node -> cn_Type == ID_FTXT)
  352.                                 {
  353.                                     LONG Count = Node -> cn_Size;
  354.  
  355.                                     if(BytesRead + Count > Bytes)
  356.                                         Count = Bytes - BytesRead;
  357.  
  358.                                     if(Count > 0)
  359.                                     {
  360.                                         if((Count = ReadChunkBytes(Handle,Index,Count)) > 0)
  361.                                         {
  362.                                             Index        += Count;
  363.                                             BytesRead    += Count;
  364.                                         }
  365.                                     }
  366.                                 }
  367.                             }
  368.  
  369.                             Bytes = BytesRead;
  370.                         }
  371.                     }
  372.  
  373.                     CloseIFF(Handle);
  374.                 }
  375.             }
  376.  
  377.             CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  378.         }
  379.  
  380.         FreeIFF(Handle);
  381.     }
  382.  
  383.     if(Store && !Bytes)
  384.     {
  385.         FreeVecPooled(Store);
  386.  
  387.         Store = NULL;
  388.     }
  389.  
  390.     *Buffer    = Store;
  391.     *Size    = Bytes;
  392.  
  393.     return((BYTE)(Store != NULL));
  394. }
  395.  
  396.     /* AddClip(STRPTR Buffer,LONG Size):
  397.      *
  398.      *    Merge previous clipboard contents with new text,
  399.      *    then store the new string in the clipboard.
  400.      */
  401.  
  402. BYTE __regargs
  403. AddClip(STRPTR Buffer,LONG Size)
  404. {
  405.     LONG    Bytes;
  406.     APTR    Store;
  407.  
  408.     if(GetClipContents(Config -> ClipConfig -> ClipboardUnit,&Store,&Bytes))
  409.     {
  410.         struct IFFHandle    *Handle;
  411.         BYTE             Success = FALSE;
  412.  
  413.         if(Handle = AllocIFF())
  414.         {
  415.             if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
  416.             {
  417.                 InitIFFasClip(Handle);
  418.  
  419.                 if(!OpenIFF(Handle,IFFF_WRITE))
  420.                 {
  421.                     if(!PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
  422.                     {
  423.                         if(!PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN))
  424.                         {
  425.                             if(WriteChunkBytes(Handle,Store,Bytes) == Bytes)
  426.                             {
  427.                                 if(WriteChunkBytes(Handle,Buffer,Size) == Size)
  428.                                 {
  429.                                     if(!PopChunk(Handle))
  430.                                         Success = TRUE;
  431.                                 }
  432.                             }
  433.                         }
  434.                     }
  435.  
  436.                     if(Success)
  437.                     {
  438.                         if(PopChunk(Handle))
  439.                             Success = FALSE;
  440.                     }
  441.  
  442.                     CloseIFF(Handle);
  443.                 }
  444.  
  445.                 CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  446.             }
  447.  
  448.             FreeIFF(Handle);
  449.         }
  450.  
  451.         FreeVecPooled(Store);
  452.  
  453.         return(Success);
  454.     }
  455.     else
  456.         return(SaveClip(Buffer,Size));
  457. }
  458.  
  459.     /* SaveClip(STRPTR Buffer,LONG Size):
  460.      *
  461.      *    Send a given text buffer to the clipboard.
  462.      */
  463.  
  464. BYTE __regargs
  465. SaveClip(STRPTR Buffer,LONG Size)
  466. {
  467.     BYTE Success = FALSE;
  468.  
  469.     if(Size > 0)
  470.     {
  471.         struct IFFHandle *Handle;
  472.  
  473.         if(Handle = AllocIFF())
  474.         {
  475.             if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
  476.             {
  477.                 InitIFFasClip(Handle);
  478.  
  479.                 if(!OpenIFF(Handle,IFFF_WRITE))
  480.                 {
  481.                     if(!PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
  482.                     {
  483.                         if(!PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN))
  484.                         {
  485.                             if(WriteChunkBytes(Handle,Buffer,Size) == Size)
  486.                             {
  487.                                 if(!PopChunk(Handle))
  488.                                     Success = TRUE;
  489.                             }
  490.                         }
  491.                     }
  492.  
  493.                     if(Success)
  494.                     {
  495.                         if(PopChunk(Handle))
  496.                             Success = FALSE;
  497.                     }
  498.  
  499.                     CloseIFF(Handle);
  500.                 }
  501.  
  502.                 CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  503.             }
  504.  
  505.             FreeIFF(Handle);
  506.         }
  507.     }
  508.  
  509.     return(Success);
  510. }
  511.  
  512.     /* LoadClip(STRPTR Buffer,LONG Size):
  513.      *
  514.      *    Put the contents of the clipboard into a given
  515.      *    buffer. Note that only the first FTXT chunk will
  516.      *    be read. Since this code will only be called by
  517.      *    the clipboard server process which serves the
  518.      *    string gadget editing hook, this will hopefully
  519.      *    not be fatal. If you want more data to be read,
  520.      *    including multiple FTXT chunks, use the OpenClip(),
  521.      *    GetClip(), CloseClip() combo above.
  522.      */
  523.  
  524. LONG __regargs
  525. LoadClip(STRPTR Buffer,LONG Size)
  526. {
  527.     struct IFFHandle    *Handle;
  528.     LONG             Bytes = 0;
  529.  
  530.     if(Handle = AllocIFF())
  531.     {
  532.         if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
  533.         {
  534.             InitIFFasClip(Handle);
  535.  
  536.             if(!OpenIFF(Handle,IFFF_READ))
  537.             {
  538.                 if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  539.                 {
  540.                     if(!ParseIFF(Handle,IFFPARSE_SCAN))
  541.                     {
  542.                         struct ContextNode *ContextNode = CurrentChunk(Handle);
  543.  
  544.                         if(ContextNode -> cn_Type == ID_FTXT)
  545.                         {
  546.                             if(Size > ContextNode -> cn_Size)
  547.                                 Size = ContextNode -> cn_Size;
  548.  
  549.                             if(ReadChunkRecords(Handle,Buffer,Size,1))
  550.                                 Bytes = Size;
  551.                         }
  552.                     }
  553.                 }
  554.  
  555.                 CloseIFF(Handle);
  556.             }
  557.  
  558.             CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  559.         }
  560.  
  561.         FreeIFF(Handle);
  562.     }
  563.  
  564.     return(Bytes);
  565. }
  566.